package Java2Test.dynamicproxy;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工具类，用于创建大明星的动态代理对象
 * 实现了对明星方法调用前的额外处理，包括业务方法和生活方法
 */
public class ProxyUtil {
    /**
     * 创建大明星的业务代理对象
     *
     * @param bigStar 被代理的大明星对象
     * @return 实现了Star接口的代理对象
     */
    public static Star createStarProxy(BigStar bigStar) {
        // 使用JDK动态代理创建代理对象
        Star star = (Star) Proxy.newProxyInstance(
                // 类加载器：使用ProxyUtil类的类加载器
                ProxyUtil.class.getClassLoader(),
                // 代理对象要实现的接口：Star接口
                new Class[]{Star.class},
                // 调用处理器：处理代理对象方法的调用
                new InvocationHandler() {
                    /**
                     * 代理对象方法调用时执行的方法
                     *
                     * @param proxy 代理对象
                     * @param method 被调用的方法
                     * @param args 方法参数
                     * @return 方法返回值
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 根据调用的方法名进行不同的前置处理
                        if ("sing".equals(method.getName())) {
                            // 唱歌前的准备工作
                            System.out.println("准备话筒, 收钱");
                        } else if ("dance".equals(method.getName())) {
                            // 跳舞前的准备工作
                            System.out.println("准备场地, 收钱");
                        }

                        // 调用被代理对象的实际方法
                        return method.invoke(bigStar, args);
                    }
                }
        );
        return star;
    }

    /**
     * 创建大明星的生活代理对象
     *
     * @param bigStar 被代理的大明星对象
     * @return 实现了Life接口的代理对象
     * @throws NoSuchFieldException 如果无法找到指定字段
     */
    public static Life creatLifeProxy(BigStar bigStar) throws NoSuchFieldException {
        // 使用JDK动态代理创建代理对象
        Life life = (Life) Proxy.newProxyInstance(
                // 类加载器：使用ProxyUtil类的类加载器
                ProxyUtil.class.getClassLoader(),
                // 代理对象要实现的接口：Life接口
                new Class[]{Life.class},
                // 调用处理器：处理代理对象方法的调用
                new InvocationHandler() {
                    /**
                     * 代理对象方法调用时执行的方法
                     *
                     * @param proxy 代理对象
                     * @param method 被调用的方法
                     * @param args 方法参数
                     * @return 方法返回值
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 根据调用的方法名进行不同的前置处理
                        if ("eat".equals(method.getName())) {
                            // 吃饭前的准备工作
                            System.out.println("准备碗筷");
                        } else if ("sleep".equals(method.getName())) {
                            // 睡觉前的准备工作
                            System.out.println(bigStar.getName() + "睡前喝杯牛奶");
                        }

                        // 调用被代理对象的实际方法
                        return method.invoke(bigStar, args);
                    }
                });

        return life;
    }
}
